home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 18 code / Hierarchical Lists / Src / TwistDownList.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-16  |  11.3 KB  |  290 lines  |  [TEXT/KAHL]

  1. /*                                    TwistDownList.h                                */
  2. /*
  3.  * List In A List Sample
  4.  * TwistDownList.h
  5.  * Copyright © 1993-94 Apple Computer Inc.
  6.  *
  7.  * Note that "list" is ambiguous, referring either to a List Manager list or to
  8.  * a "Lisp-like" list. In the following documentation, "cell" will always refer
  9.  * to a List Manager list cell, while "element" will always refer to a Lisp
  10.  * cell. Note that elements are not always displayed by the List Manager.
  11.  */
  12. #ifndef _TwistDownList_
  13. #define _TwistDownList_
  14.  
  15. #ifndef REZ
  16. #ifndef THINK_C                /* MPW includes            */
  17. #include <Types.h>
  18. #include <Lists.h>
  19. #include <QuickDraw.h>
  20. #include <Packages.h>
  21. #include <Traps.h>
  22. #include <Windows.h>
  23. #endif
  24. #ifndef TRUE
  25. #define TRUE                1
  26. #define FALSE                0
  27. #endif
  28. #ifndef NULL
  29. #define NULL                0
  30. #endif
  31. /*
  32.  * This is the resource ID of the callback stub that must be defined in the
  33.  * application's resource fork. See the example in ListInAList.r.
  34.  */
  35. #define LDEF_Stub            1024
  36. /*
  37.  * TwistDownClickState is the value returned by DoTwistDownClick.
  38.  */
  39. typedef enum {
  40.     kTwistDownNotInList = 0,            /* The click was not in this list        */
  41.     kTwistDownNoClick,                    /* User changed mind                    */
  42.     kTwistDownButtonClick,                /* Clicked on twist-down button            */
  43.     kTwistDownClick,                    /* Single-click on list datum            */
  44.     kTwistDownDoubleClick                /* Double-click on list datum            */
  45. } TwistDownClickState;
  46.  
  47. /*
  48.  * This is the information needed to manage the twist-down display list. It is,
  49.  * essentially, a classical Lisp list with recursively-defined sublists. Each
  50.  * element contains enough information to display one component. This list is
  51.  * stored in a handle stored in the list's private data handle. The ListManager
  52.  * list cells contain TwistDownHdl pointers to the visible elements.
  53.  * A value of NULL in nextElement indicates the end of a list or sublist.
  54.  * A value of NULL in subElement means that there are no sub-elements (this
  55.  * is a leaf). Note that the Macintosh memory manager handles garbage collection.
  56.  *
  57.  * The flag bits have the following meanings:
  58.  *    kHasTwistDown        This list element is a sub-list (it may be empty).
  59.  *                        Draw the twist-down button (even if subElement is NULL).
  60.  *    kShowSubList        This list element is has a sub-list and the user wants
  61.  *                        to see the contents of the sub-list, too.
  62.  *    kOldShowSubList        This would be used to save the state of the kShowSubList
  63.  *                        flag if it needs to be changed temporarily (to show
  64.  *                        the entire hierarchy, for example).
  65.  * The following flags are only needed by the mouse-click handler.
  66.  *    kDrawButtonFilled    This is used by the mouse-click handler to signal
  67.  *                        "mouse-down in button." The LDEF fills the button area.
  68.  *    kOnlyRedrawButton    This is used by the mouse-click handler to signal the
  69.  *                        LDEF to draw only the button, but not the list content.
  70.  *    kDrawIntermediate    The user is expanding/collapsing the folder. Draw
  71.  *                        the animation triangle.
  72.  *    kSelectedElement    This element was selected in the display list. This is
  73.  *                        a temporary value needed when the list is expanded or
  74.  *                        contracted.
  75.  *    kEraseButtonArea    If we are only hiliting the button (while the user has
  76.  *                        pressed the mouse in the button area), we don't need to
  77.  *                        erase the button before redrawing it. When the user clicks
  78.  *                        -- releases the mouse in the button -- the button shape
  79.  *                        will change, so the old shape must be erased. This is
  80.  *                        controlled by this flag.
  81.  */
  82. #define kHasTwistDown        0x0001                /* This element has a sub-list    */
  83. #define    kShowSublist        0x0002                /* Display the sub-list content    */
  84. #define    kOldShowSublist        0x0004                /* Save kShowSublist state        */
  85. #define    kSelectedElement    0x0008                /* Copy "selected" from List    */
  86. #define    kDrawButtonFilled    0x0010                /* Signal "mouseDown" in button    */
  87. #define    kOnlyRedrawButton    0x0020                /* Signal "tracking mouse"        */
  88. #define kDrawIntermediate    0x0040                /* Draw the animation polygon    */
  89. #define    kEraseButtonArea    0x0080                /* Need complete button redraw    */
  90.     
  91. struct TwistDownRecord {
  92.     struct TwistDownRecord    **nextElement;        /* CDR - next on this "level"    */
  93.     struct TwistDownRecord    **subElement;        /* CAR - first in a sublist        */
  94.     short                indentLevel;            /* Indentation depth            */
  95.     unsigned short        flag;                    /* TwistDownFlags                */
  96.     unsigned short        dataLength;                /* Length of actual datum        */
  97.     unsigned char        data[1];                /* Datum to display                */
  98. };
  99. typedef struct TwistDownRecord    TwistDownRecord, *TwistDownPtr, **TwistDownHdl;
  100.  
  101. /*
  102.  * This is the function that is called to draw the user-specified list cell
  103.  * contents. The port and font have been properly initialized. If this parameter
  104.  * is specified as NULL, DrawText will be used. Note that the application can use
  105.  * the list's refCon to pass other data to the drawing procedure. Applications
  106.  * should not have any other need to access the list handle or its contents.
  107.  */
  108. typedef pascal void        (*TwistDownDrawProc)(
  109.         ListHandle            twistDownListHdl,    /* The list itself                */
  110.         const Ptr            dataPtr,            /* -> user data in record        */
  111.         unsigned short        dataLength,            /* length of user datum            */
  112.         const Rect            *viewRect            /* Draw in this area            */
  113.     );
  114.  
  115. /*
  116.  * Create a twist-down list. Before calling, you must set the port to the current
  117.  * window and specify the font and font size that is to be used to draw the list.
  118.  * NewTwistDownList creates an empty one-column list with a vertical scroll bar
  119.  * and no grow box. Only one item may be selected at a time; but this could
  120.  * be changed by the application without difficulty.
  121.  *
  122.  * Note: unlike LNew, you should specify a correct viewRect: the scroll bars and
  123.  * frame will be created inside the view rect.
  124.  *
  125.  * The TwistDownDrawProc will be called to draw a selection. If specified as
  126.  * NULL, DrawText will be called.
  127.  *
  128.  * The tabIndent parameter should be set to the amount to indent successive levels
  129.  * (zero means no indentation). Setting it to the widMax value from the current
  130.  * font seems reasonable.
  131.  *
  132.  * canHiliteSelection should be TRUE for normal selection (the selection is
  133.  * hilited). It should be FALSE if you want to supress selection. Because
  134.  * hirearchical lists often "select" by revealing a sub-topic, this may be
  135.  * more reasonable in many cases.
  136.  *
  137.  * isLeftJustify should be set TRUE for systems using the Roman alphabet. It would
  138.  * be set FALSE for right-to-left languages such as Arabic and Hebrew. It is used
  139.  * to configure the direction of the buttons and the location of text within
  140.  * the displayed list cell.
  141.  */
  142. ListHandle                        NewTwistDownList(
  143.         const Rect                    *viewRect,
  144.         TwistDownDrawProc            drawProc,
  145.         unsigned short                tabIndent,
  146.         Boolean                        canHiliteSelection,
  147.         Boolean                        isLeftJustify
  148.     );
  149. /*
  150.  * Dispose of a Twist Down List and its private storage. The application program
  151.  * must itself dispose of the list data. theList may be NULL.
  152.  */
  153. void                            DisposeTwistDownList(
  154.         ListHandle                    theList
  155.     ); 
  156. /*
  157.  * CreateTwistDownButtons is called, internally, when the list is created.
  158.  * if the application program changes the list cell height (by calling LSize),
  159.  * or changes the direction of text it must re-call CreateTwistDownButtons
  160.  * to re-create the twist-down buttons.
  161.  */
  162. void                            CreateTwistDownButtons(
  163.         ListHandle                    theList
  164.     );
  165.  
  166. /*
  167.  * DoTwistDownClick handles all processing after a click in the list window.
  168.  * It returns an indication of the user action:
  169.  *    kTwistDownNotInList
  170.  *        The click was not in this list. Your application may ignore this click or
  171.  *        take other appropriate action.
  172.  *    kTwistDownNoClick
  173.  *        The user released the mouse outside of the list area: this click should be
  174.  *        ignored.
  175.  *    kTwistDownButtonClick
  176.  *        The user clicked on the twist-down button. Expand or contract the list as
  177.  *        appropriate.
  178.  *    kTwistDownClick
  179.  *        The user clicked (once) on a list datum. The application should treat this
  180.  *        as an item selection (or, it may be a click in the scroll bar). This is
  181.  *        the result of a FALSE return from LClick.
  182.  *    kTwistDownDoubleClick
  183.  *        The user double-clicked on a list datum. The application should open this
  184.  *        item or take other appropriate action. This is the result of a TRUE
  185.  *        return from LClick.
  186.  *
  187.  * If DoTwistDownClick returns kTwistDownButtonClick, kTwistDownClick, or
  188.  * kTwistDownDoubleClick, selectedListCell will be set to the cell that the user
  189.  * clicked on.
  190.  */
  191. TwistDownClickState                DoTwistDownClick(
  192.         ListHandle                    theList,
  193.         const EventRecord            *eventRecordPtr,
  194.         Cell                        *selectedListCell
  195.     );
  196. /*
  197.  * ExpandOrCollapseTwistdownSubList is called when the user clicks on the
  198.  * twist-down button. index and selectedListCell are the values returned by
  199.  * DoTwistDownClick.
  200.  */
  201. void                            ExpandOrCollapseTwistDownList(
  202.         ListHandle                    theList,
  203.         Cell                        selectedListCell
  204.     );
  205. /*
  206.  * CreateVisibleList is called when the list is created. It stores the list
  207.  * head into cell [0, 0] and calls BuildVisibleList to instantiate the display.
  208.  */
  209. void                            CreateVisibleList(
  210.         ListHandle                    theList,
  211.         TwistDownHdl                twistDownHdl
  212.     );
  213. /*
  214.  * BuildVisibleList is called when the list is created, or when the user clicks on
  215.  * a twist-down button. selectedRow is the first row that needs to be redrawn. The
  216.  * head of the entire list has been stored into cell [0, 0].
  217.  */
  218. void                            BuildVisibleList(
  219.         ListHandle                    theList,
  220.         short                        selectedRow
  221.     );
  222. /*
  223.  * GetTwistDownElementHandle returns the TwistDownHdl that is stored in a List
  224.  * cell. It will return NULL if the cell is out of bounds.
  225.  */
  226. TwistDownHdl                    GetTwistDownElementHandle(
  227.         ListHandle                    theList,
  228.         Cell                        theCell
  229.     );
  230.  
  231. /*
  232.  * MakeTwistDownElement adds an element to a linked list. It is designed to create
  233.  * elements in a hierarchical linked-list where each element may be followed by a
  234.  * successor (on the same "level") and/or by a child list (on a lower "level").
  235.  * The parameters are as follows:
  236.  *    previousElement
  237.  *        This has a handle to the predecessor to this element. PreviousElement
  238.  *        should be NULL if this is the first element.
  239.  *    indentLevel
  240.  *        This is the indentation-level of this list element. It is only used to tab
  241.  *        the list elements on the visual display. If you never want tabbing, set
  242.  *        tabIndent to zero when the list was created. Indents start at zero.
  243.  *    dataLength
  244.  *        This is the length of the list element datum.
  245.  *    dataPtr
  246.  *        This is a pointer to the first byte of the list element datum. If NULL,
  247.  *        a data block of the requisite size will be created, but the caller is
  248.  *        responsible for filling it in.
  249.  *    result
  250.  *        If MakeElement succeeds, result will will contain a handle to the
  251.  *        list element it created. This is needed to create a successor
  252.  *        element.
  253.  */
  254. OSErr                            MakeTwistDownElement(
  255.         TwistDownHdl                previousElement,
  256.         short                        indentLevel,
  257.         unsigned short                dataLength,
  258.         Ptr                            dataPtr,
  259.         TwistDownHdl                *result
  260.     );
  261.  
  262. /*
  263.  * This recursive function disposes of the argument list that has the argument
  264.  * at its head, and of all sublists linked to this list. If userProc is non-NULL,
  265.  * it will be called when disposing each handle. This allows the caller to
  266.  * store handle or pointer data within a list element.
  267.  */
  268. typedef void    (*DisposeTwistDownCallback)(
  269.         TwistDownHdl                twistDownHdl,
  270.         void                        *userData
  271.     );
  272.         
  273. void
  274. DisposeTwistDownHdl(
  275.         TwistDownHdl                twistDownHdl,
  276.         DisposeTwistDownCallback    userProc,
  277.         void                        *userData
  278.     );
  279.  
  280. /*
  281.  * Count the number of elements in the list (whether visible or not).
  282.  */
  283. unsigned long                    CountListElements(
  284.         TwistDownHdl                twistDownHdl
  285.     );
  286.  
  287.  
  288. #endif    /* REZ                */
  289. #endif    /* _TwistDownList_    */
  290.